package com.wkbb.basic.controller.manage;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.wkbb.basic.model.Organization;
import com.wkbb.basic.service.*;
import com.wkbb.common.base.BaseController;
import com.wkbb.common.constants.ErrorCode;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.OrganizationDto;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.enums.OrganizationTypeEnum;
import com.wkbb.common.enums.TypeSetEnum;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.text.Collator;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author luowenyan
 * @version V1.0
 * @className EducationStatManagerController
 * @description TODO
 * @date 2019/10/23 10:12
 */
@RestController
@Api(description = "教育局统计报表管理(后台管理)")
@RequestMapping("/basic/{apiVersion}/education/stat/manage")
@Slf4j
public class EducationStatManageController extends BaseController {

    @Autowired
    private EducationStatService educationStatService;

    @Autowired
    private OrganizationService organizationService;

    @Autowired
    private StudentService studentService;

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private FamilyService familyService;

    //1.获取系统时间接口
    //2.查询省份/市区下的学校列表接口和学校统计接口
    //3.学生晨检统计接口
    //4.学生统计(人数统计)接口
    //5.学生统计(男女统计)接口
    //6.学生统计(考勤统计)接口 (attend)
    //7.老师统计接口
    //8.家长统计接口
    //9.地图统计接口(老刘要写)

    /**
     * 学校统计接口,根据当前登陆的后台管理账户,获取到orgId,orgId就是教育局Id,根据orgId获取教育局下的所有的学校,并根据类型来统计,直接先查询一个列表,再按照学校性质来统计
     * @param apiVersion
     * @return
     */
    @ApiOperation("学校统计接口")
    @GetMapping(value = "getOrgCountByType")
    public ResultDTO<Map<String,Object>> getOrgCountByType(
            @ApiParam(value = "接口版本",required = true,defaultValue = "v1") @PathVariable(value = "apiVersion",required = true) String apiVersion
        ){
        try{
            UserDto userDto = getUserByLogin();
            if (userDto == null) {
                return new ResultDTO(ErrorCode.USER_NOT_EXIST);
            }
            OrganizationDto organizationDto = super.getOrgByUser(userDto);
            if(null == organizationDto || organizationDto.getOrgType().intValue()!=OrganizationTypeEnum.EDUCATION.getValue().intValue()){
                return new ResultDTO<>(ErrorCode.LOGIN_ACCOUNT_ERROR);
            }

            List<Organization> organizationList = organizationService.getOrganizationList(organizationDto);

            //新增一个接口,接口按照学校性质来统计 性质(1公办 2民办 3合办 4普惠)
            List<Map<String,Object>> orgMapList = organizationService.getOrgCountByType(organizationDto);
            JSONArray typeSetJsonList = new JSONArray();
            Integer totalOrgCount = 0;
            String key1 = "typeSet";
            String key2 = "count";
            if(CollectionUtils.isNotEmpty(orgMapList)) {
                for (Map<String, Object> map : orgMapList) {
                    JSONObject json = JSON.parseObject(JSONUtils.toJSONString(map));
                    Integer typeSet = Integer.valueOf(json.get(key1).toString());
                    Integer value = Integer.valueOf(json.get(key2).toString());
                    totalOrgCount = totalOrgCount + value;
                    setJsonList(typeSetJsonList,key1,TypeSetEnum.getDesc(typeSet),key2,value);
                }
            }
            //总学校数量
            Map<String,Object> returnMap = new HashMap<>();
            returnMap.put("totalOrgCount",totalOrgCount);
            returnMap.put("typeSetStat",typeSetJsonList);
            returnMap.put("orgName",organizationDto.getName());
            returnMap.put("childOrgList",organizationList);
            return new ResultDTO<Map<String,Object>>(returnMap);
        }catch (Exception e){
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    /* 基础条形图
    var data = [{
        gradeName: '托班',
        count: 34
    }, {
        gradeName: '小小班',
        count: 85
    }, {
        gradeName: '小班',
        count: 103
    }, {
        gradeName: '中班',
        count: 142
    }, {
        gradeName: '大班',
        count: 251
    }];*/
    /**
     * 基础环图
     * var data = [{
     *     sex: '男',
     *     count: 40,
     *     percent: 0.4
     *   }, {
     *     sex: '女',
     *     count: 60,
     *     percent: 0.6
     *   }];
     */
    //4.学生统计(人数统计)接口 getStudentStatByGrade
    //5.学生统计(男女统计)接口 getStudentStatBySex
    //6.学生统计(考勤统计)接口 getStudentStatByAttend
    @ApiOperation("学生统计(人数统计)接口")
    @GetMapping(value = "getStudentCountStat")
    public ResultDTO<Map<String,Object>> getStudentCountStat(
            @ApiParam(value = "接口版本",required = true,defaultValue = "v1") @PathVariable(value = "apiVersion",required = true) String apiVersion,
            @ApiParam(value = "学校ID",required = false) @RequestParam(name = "realOrgId",required = false) Long realOrgId){
        try{
            UserDto userDto = getUserByLogin();
            if (userDto == null) {
                return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
            }
            //查询到教育局
            OrganizationDto organizationDto = super.getOrgByUser(userDto);
            if(null == organizationDto || organizationDto.getOrgType().intValue()!=OrganizationTypeEnum.EDUCATION.getValue().intValue()){
                return new ResultDTO<>(ErrorCode.LOGIN_ACCOUNT_ERROR);
            }
            Long educationId = organizationDto.getId();
            Map<String,Object> returnMap = new LinkedHashMap<>();
            //1.基础条形图
            //2.基础环图
            //3.项目整体监控图
            //教育局ID,学校ID,传2个值
            //如果统计全部学校,参数educationId不能为空
            Map<String,Object> returnGradeMap = new HashMap<>();
            Map<String,Object> returnSexMap = new HashMap<>();
            JSONArray sexJsonList = new JSONArray();
            JSONArray gradeJsonList = new JSONArray();
            if (null != educationId && realOrgId == null) {
                //Integer teacherTotalCount = 0;
                //Integer studentTotalCount = 0;
                List<Organization> organizationList = organizationService.getOrganizationList(organizationDto);
                for(Organization organization : organizationList){
                    Long orgId = organization.getId();
                    List<Map<String,Object>> gradeMapList = studentService.getStudentStatByGrade(orgId);
                    log.info("------学校ID:={},gradeMapList={}",orgId,gradeMapList);
                    List<Map<String,Object>> sexMapList = studentService.getStudentStatBySex(orgId);
                    log.info("------学校ID:={},sexMapList={}",orgId,sexMapList);

                    getMapByKey(returnGradeMap,gradeMapList,"gradeName","count");
                    getMapByKey(returnSexMap,sexMapList,"sex","count");

                    //统计全校老师人数
                    //teacherTotalCount = educationStatService.getCountByRoleType(organization.getId(), RoleTypeEnum.TEACHER);
                    //统计全校学生人数
                    //studentTotalCount = educationStatService.getCountByRoleType(organization.getId(), RoleTypeEnum.STUDENT);
                }
                getJsonListByKey(gradeJsonList,returnGradeMap,"gradeName","count");
                getJsonListByKey(sexJsonList,returnSexMap,"sex","count");

                returnMap.put("gradeStat",mergeData(gradeJsonList));
                returnMap.put("sexStat",suppSexData(sexJsonList));
                return new ResultDTO<Map<String,Object>>(returnMap);
            } else if (realOrgId != null && null!=educationId) {
                //单个学校,按照年级统计
                List<Map<String,Object>> gradeMapList = studentService.getStudentStatByGrade(realOrgId);
                getJsonListByKey(gradeJsonList,gradeMapList,"gradeName","count");
                //单个学校,按照性别统计
                List<Map<String,Object>> sexMapList = studentService.getStudentStatBySex(realOrgId);
                getJsonListByKey(sexJsonList,sexMapList,"sex","count");

                returnMap.put("gradeStat",mergeData(gradeJsonList));
                returnMap.put("sexStat",suppSexData(sexJsonList));
                return new ResultDTO<Map<String,Object>>(returnMap);
            } else{
                return new ResultDTO(ErrorCode.PARAM_MISMATCH);
            }
        }catch (Exception e){
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    /**
     * [
     *       {
     *         positionName: "任课老师",
     *         count: 40
     *       },
     *       {
     *         positionName: "保育员",
     *         count: 21
     *       },
     *       {
     *         positionName: "营养师",
     *         count: 17
     *       },
     *       {
     *         positionName: "保安",
     *         count: 13
     *       },
     *       {
     *         positionName: "园长",
     *         count: 9
     *       }
     *     ];
     * @param apiVersion
     * @param realOrgId
     * @return
     */
    //7.老师统计接口
    @ApiOperation("老师统计接口(此接口未调试,等待小邓调试)")
    @GetMapping(value = "getEmployeeCountStat")
    public ResultDTO<JSONArray> getEmployeeCountStat(
            @ApiParam(value = "接口版本",required = true,defaultValue = "v1") @PathVariable(value = "apiVersion",required = true) String apiVersion,
            @ApiParam(value = "学校ID",required = false) @RequestParam(name = "realOrgId",required = false) Long realOrgId) {
        try {
            UserDto userDto = getUserByLogin();
            if (userDto == null) {
                return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
            }
            //查询到教育局
            OrganizationDto organizationDto = super.getOrgByUser(userDto);
            if(null == organizationDto || organizationDto.getOrgType().intValue()!=OrganizationTypeEnum.EDUCATION.getValue().intValue()){
                return new ResultDTO<>(ErrorCode.LOGIN_ACCOUNT_ERROR);
            }
            Long educationId = organizationDto.getId();

            Map<String,Object> returnPositionMap = new HashMap<>();
            JSONArray positionJsonList = new JSONArray();
            if (null != educationId && realOrgId == null) {
                List<Organization> organizationList = organizationService.getOrganizationList(organizationDto);
                List<Map<String,Object>> employeeMapList = employeeService.getTearcherCountStatByOrgList(organizationList);
                getJsonListByKey(positionJsonList,employeeMapList,"positionName","count");
                return new ResultDTO<JSONArray>(positionJsonList);
            } else if (realOrgId != null && null!=educationId) {
                //只查询单个学校的情况
                List<Map<String,Object>> employeeMapList = employeeService.getTeacherCountStatByOrgId(realOrgId);
                getJsonListByKey(positionJsonList,employeeMapList,"positionName","count");
                return new ResultDTO<JSONArray>(positionJsonList);
            } else{
                return new ResultDTO(ErrorCode.PARAM_MISMATCH);
            }
        }catch (Exception e){
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

/**
 * [
 *       {
 *         relationType: "任课老师",
 *         count: 40
 *       },
 *       {
 *         relationType: "保育员",
 *         count: 21
 *       },
 *       {
 *         relationType: "营养师",
 *         count: 17
 *       },
 *       {
 *         relationType: "保安",
 *         count: 13
 *       },
 *       {
 *         relationType: "园长",
 *         count: 9
 *       }
 *     ];*/
    //8.家长统计接口
    @ApiOperation("家长统计接口")
    @GetMapping(value = "getFamilyCountStat")
    public ResultDTO<JSONArray> getFamilyCountStat(
            @ApiParam(value = "接口版本",required = true,defaultValue = "v1") @PathVariable(value = "apiVersion",required = true) String apiVersion,
            @ApiParam(value = "学校ID",required = false) @RequestParam(name = "realOrgId",required = false) Long realOrgId) {
        try {
            UserDto userDto = getUserByLogin();
            if (userDto == null) {
                return new ResultDTO<>(ErrorCode.USER_NOT_EXIST);
            }
            //查询到教育局
            OrganizationDto organizationDto = super.getOrgByUser(userDto);
            if(null == organizationDto || organizationDto.getOrgType().intValue()!=OrganizationTypeEnum.EDUCATION.getValue().intValue()){
                return new ResultDTO<>(ErrorCode.LOGIN_ACCOUNT_ERROR);
            }
            Long educationId = organizationDto.getId();

            Map<String,Object> returnRelationTypeMap = new HashMap<>();
            JSONArray relationTypeJsonList = new JSONArray();
            if (null != educationId && realOrgId == null) {
                //查询教育局下多个学校的统计情况
                List<Organization> organizationList = organizationService.getOrganizationList(organizationDto);
                for(Organization organization : organizationList){
                    List<Map<String,Object>> relationTypeMapList = familyService.getFamilyCountStatByOrgId(organization.getId());
                    getMapByKey(returnRelationTypeMap,relationTypeMapList,"relationType","count");
                }
                getJsonListByKey(relationTypeJsonList,returnRelationTypeMap,"relationType","count");
                return new ResultDTO<JSONArray>(relationTypeJsonList);
            } else if (realOrgId != null && null!=educationId) {
                //只查询单个学校的情况
                List<Map<String,Object>> relationTypeMapList = familyService.getFamilyCountStatByOrgId(realOrgId);
                getJsonListByKey(relationTypeJsonList,relationTypeMapList,"relationType","count");
                return new ResultDTO<JSONArray>(relationTypeJsonList);
            } else{
                return new ResultDTO(ErrorCode.PARAM_MISMATCH);
            }
        }catch (Exception e){
            e.printStackTrace();
            return new ResultDTO(ErrorCode.SYSTEM_EXCEPTION);
        }
    }

    private Map<String, Object> getReturnMap(Map<String, Object> returnMap,String key,Integer value){
        if(!returnMap.containsKey(key)){
            returnMap.put(key,value);
        }else{
            Integer totalCount = (Integer) returnMap.get(key);
            totalCount = totalCount + value;
            returnMap.put(key,totalCount);
        }
        return returnMap;
    }

    /**
     * 一个公共的获取map的方法,此方法只适合获取两个key的值
     * @param returnMap
     * @param mapList
     * @param key1
     * @param key2
     * @return
     */
    private Map<String, Object> getMapByKey(Map<String, Object> returnMap, List<Map<String, Object>> mapList,String key1,String key2){
        if(CollectionUtils.isNotEmpty(mapList)) {
            for (Map<String, Object> map : mapList) {
                JSONObject json = JSON.parseObject(JSONUtils.toJSONString(map));
                if(!json.containsKey(key1)) {
                    return returnMap;
                }
                String name = json.get(key1).toString();
                Integer count = Integer.valueOf(json.get(key2).toString());
                getReturnMap(returnMap, name, count);
            }
        }
        return returnMap;
    }

    private JSONArray getJsonListByKey(JSONArray jsonList,Map<String,Object> map,String key1,String key2){
        if(!map.isEmpty()){
            for(Map.Entry<String, Object> entry:map.entrySet()) {
                String name = entry.getKey();
                Integer value = (Integer) entry.getValue();
                setJsonList(jsonList,key1,name,key2,value);
            }
        }
        return jsonList;
    }

    private JSONArray getJsonListByKey(JSONArray jsonList, List<Map<String, Object>> mapList,String key1,String key2){
        if(CollectionUtils.isNotEmpty(mapList)) {
            for (Map<String, Object> map : mapList) {
                JSONObject json = JSON.parseObject(JSONUtils.toJSONString(map));
                if(!json.containsKey(key1)){
                    return jsonList;
                }
                String name = json.get(key1).toString();
                Integer value = Integer.valueOf(json.get(key2).toString());
                setJsonList(jsonList,key1,name,key2,value);
            }
        }
        return jsonList;
    }

    private JSONArray setJsonList(JSONArray jsonList,String key1,String name,String key2,Integer value){
        JSONObject jsonObject = new JSONObject();
        jsonObject.put(key1,name);
        jsonObject.put(key2,value);
        jsonList.add(jsonObject);
        return jsonList;
    }

    /**
     * 合并数据
     * @param gradeJsonList
     */
    private JSONArray mergeData(JSONArray gradeJsonList){
        //合并班级 小小班/托班 大大班/学前班
        String tobinName = "";
        String preschoolName = "";
        Integer tobinCount = 0;
        Integer preschoolCount = 0;
        JSONArray toBeDelete = new JSONArray();
        JSONArray toBeAdd = new JSONArray();
        for(int i=0;i<gradeJsonList.size();i++){
            JSONObject job = gradeJsonList.getJSONObject(i);  // 遍历 jsonarray 数组，把每一个对象转成 json 对象
            if(job.containsKey("gradeName")){
                String gradeName = job.get("gradeName").toString();
                Integer count = Integer.valueOf(job.get("count").toString());
                if(gradeName.equals("小小班") || gradeName.equals("托班")){
                    if(StringUtils.isEmpty(tobinName)){
                        tobinName = new String("小小班/托班");
                    }
                    tobinCount = tobinCount + count;
                    toBeDelete.add(job);
                }else if(gradeName.equals("大大班") || gradeName.equals("学前班")){
                    if(StringUtils.isEmpty(preschoolName)){
                        preschoolName = new String("大大班/学前班");
                    }
                    preschoolCount = preschoolCount + count;
                    toBeDelete.add(job);
                }
            }
        }
        //先删除,再添加
        if(CollectionUtils.isNotEmpty(toBeDelete)){
            gradeJsonList.removeAll(toBeDelete);
        }
        //需要排序
        //添加 小小班/托班
        if(!StringUtils.isEmpty(tobinName)){
            JSONObject tobinJson = new JSONObject();
            tobinJson.put("gradeName", tobinName);
            tobinJson.put("count", tobinCount);
            gradeJsonList.add(0,tobinJson);
        }
        //添加 大大班/学前班
        if(!StringUtils.isEmpty(preschoolName)) {
            JSONObject preschoolJson = new JSONObject();
            preschoolJson.put("gradeName", preschoolName);
            preschoolJson.put("count", preschoolCount);
            gradeJsonList.add(preschoolJson);
        }
        return gradeJsonList;
    }

    /**
     * 补充男女性别为空时候的数据
     * @param sexJsonList
     * @return
     */
    private JSONArray suppSexData(JSONArray sexJsonList){
        //补充男女数据
        boolean boyFlag = false;
        boolean girlFlag = false;
        for(int i=0;i<sexJsonList.size();i++){
            //3、把里面的对象转化为JSONObject
            JSONObject job = sexJsonList.getJSONObject(i);
            if(job.containsKey("sex")){
                String sex = job.get("sex").toString();
                if(sex.equals("男")){
                    boyFlag = true;
                }else if(sex.equals("女")){
                    girlFlag = true;
                }
            }
        }
        //添加男性
        if(boyFlag == false){
            JSONObject sexJson = new JSONObject();
            sexJson.put("sex","男");
            sexJson.put("count",0);
            sexJsonList.add(sexJson);
        }
        //添加女性
        if(girlFlag == false){
            JSONObject sexJson = new JSONObject();
            sexJson.put("sex","女");
            sexJson.put("count",0);
            sexJsonList.add(sexJson);
        }
        return sexJsonList;
    }
}
